package com.white.webserver.controller;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.white.webserver.common.dto.ForgerPasswordDto;
import com.white.webserver.common.dto.MailDto;
import com.white.webserver.common.lang.Result;
import com.white.webserver.service.IMailService;
import com.white.webserver.service.IUserService;
import com.white.webserver.entity.User;
import com.white.webserver.util.JwtUtils;
import com.white.webserver.util.PasswordUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Random;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    JwtUtils jwtUtils;
    @Autowired
    IUserService userService;
    @Autowired
    IMailService mailService;

    @Value("${config.check-code.expiration-time}") private int expirationTime;

    @CrossOrigin
    @GetMapping("/checkCode")
    public Result getCheckCode(@Validated MailDto mailDto) {
        User user = userService.getOne(new QueryWrapper<User>().eq("email", mailDto.getEmail()));
        String checkCode = String.valueOf(new Random().nextInt(899999) + 100000);
        if (user == null) {
            user = new User();
            user.setEmail(mailDto.getEmail());
            user.setStatus(0);
            user.setCheckTime(LocalDateTime.now());
            user.setCheckCode(checkCode);
            userService.save(user);
        }
        else
        {
            user.setCheckCode(checkCode);
            user.setCheckTime(LocalDateTime.now());
            userService.updateById(user);
        }
        //发送邮件
        mailService.sendEmail(mailDto.getEmail(),"404 Studio 验证码",checkCode);
        return Result.success(null);
    }

    @CrossOrigin
    @PostMapping("/forgetPassword")
    @RequiresAuthentication
    public Result forgetPassword(@Validated @RequestBody ForgerPasswordDto forgerPasswordDto) {

        User user = userService.getOne(new QueryWrapper<User>().eq("email", forgerPasswordDto.getEmail()));

        if (user == null)
        {
            return Result.fail("邮箱未注册");
        }

        if (user.getStatus() != 1) {
            return Result.fail("账户异常");
        }

        if (PasswordUtils.checkPassword(forgerPasswordDto.getPassword()) == PasswordUtils.PasswordStrength.LOW)
        {
            return Result.fail("密码强度过低");
        }

        if (!user.getCheckCode().equals(forgerPasswordDto.getCheckCode()))
        {
            return Result.fail("验证码错误");
        }

        LocalDateTime checkTime = user.getCheckTime();
        LocalDateTime nowTime = LocalDateTime.now();
        Duration duration = Duration.between(checkTime, nowTime);
        if (duration.abs().getSeconds() > expirationTime)
        {
            return Result.fail("验证码过期！");
        }

        user.setPassword(SecureUtil.md5(forgerPasswordDto.getPassword()));
        userService.updateById(user);
        SecurityUtils.getSubject().logout();

        return Result.success("密码修改成功");
    }

    @CrossOrigin
    @PostMapping("/changeAvatar")
    //@RequiresAuthentication
    public Result changeAvatar(@RequestParam("file") MultipartFile file) throws IOException
    {
        if (file.isEmpty()) {
            return Result.fail("上传失败，请选择文件");
        }

        String fileName = file.getOriginalFilename();  //获取文件原名
        String saveUri="C:/Users/白给王/IEDA Projects/WebServer/Avatar/"+fileName;        //拼接保存图片的真实地址

        File saveFile = new File(saveUri);
        //判断是否存在文件夹，不存在就创建，但其实可以直接手动确定创建好，这样不用每次保存都检测
        if (!saveFile.exists()){
            saveFile.mkdirs();
        }
        try {
            file.transferTo(saveFile);  //保存文件到真实存储路径下
        } catch (IOException e) {
            e.printStackTrace();
        }

        return Result.success("上传成功");
    }
}
